
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "baseio.h"
#include "systickapp.h"
#include "wdgfun.h"

#ifdef _STM32_
extern IWDG_HandleTypeDef hiwdg; 
#else
#define  IWDG_PRESCALER_256 1
#define  IWDG_PRESCALER_4 1
#endif

const unsigned short iWdgMax = 0xffff;
const unsigned short iWdgDebugMax = 200;
volatile unsigned short iSoftWatchCount;

void
Wdg_Set (unsigned short itemp)
{
  do
    {
      iSoftWatchCount = itemp;
    }
  while (iSoftWatchCount != itemp);
}

unsigned short
Wdg_UnitInc (unsigned short iMs)
{
  unsigned short iUnit;
  unsigned long ltemp =
    iSoftWatchCount + ((unsigned long) iMs) / _systick_step_time_ms_ + 1;

  iUnit = (ltemp >= iWdgMax) ? iWdgMax : ltemp;
  ltemp -= iUnit;
  ltemp *= _systick_step_time_ms_;
  Wdg_Set (iUnit);
  return ltemp;
}

void
Wdg_Inc (unsigned short itemp)
{
  unsigned long ltemp =
    iSoftWatchCount + ((unsigned long) itemp) / _systick_step_time_ms_ + 1;
  if (ltemp >= 0xffff)
    ltemp = 0xffff;
  Wdg_Set (ltemp);
}

#if (defined _STM32_)
static void
MX_IWDG_Init_Prescal (unsigned int iPrescaler)
{
  IWDG_HandleTypeDef hiwdg;
  hiwdg.Instance = IWDG;
  hiwdg.Init.Prescaler = iPrescaler;	//IWDG_PRESCALER_4;
  hiwdg.Init.Reload = 4095;
  if (HAL_IWDG_Init (&hiwdg) != HAL_OK)
    {
      Error_Handler ();
    }
}
#else
static void
MX_IWDG_Init_Prescal (unsigned int iPrescaler)
{
}
#endif

void
MX_IWDG_Init_app (void)
{
  MX_IWDG_Init_Prescal (IWDG_PRESCALER_256);
}

void
WatchDogInit (void)
{
  MX_IWDG_Init_Prescal (IWDG_PRESCALER_4);	//    MX_IWDG_Init_app( );
  _INTERRUPT_DISABLE ();
  while (1)
    {
      __NVIC_SystemReset ();
    }
}

void
Wdg_Fun_Int (void)
{
  if (iSoftWatchCount)
    {
      iSoftWatchCount--;
#if (defined _STM32_)
      if (hiwdg.Instance)
	HAL_IWDG_Refresh (&hiwdg);
#endif
   Wdg_Fun_IntCallBack ();
		
    }
  else
    {
      iSoftWatchCount = iWdgDebugMax;
      debug_break (_debug_errno_wdgout_);
      WatchDogInit ();
    }
  Wdg_Fun_IntCallBack ();
}

unsigned short
Wdg_Get (void)
{
  if (0 == iSoftWatchCount)
    debug_break (_debug_errno_wdgout_);
  return iSoftWatchCount;
}

__weak void
Wdg_Fun_IntCallBack (void)
{
return ;
}
